<?php

declare(strict_types=1);

namespace app\home\controller;

use app\BaseController;
use app\common\model\User\User as UserModel;
use app\common\model\Post\Post as PostModel;
use app\common\model\Post\Comment as CommentModel;
use app\common\model\User\Record as RecordModel;
use app\common\validate\Post\Comment as CommentValiDate;
use app\common\validate\User\Record as RecordValiDate;
use think\exception\ValidateException;

class Comment extends BaseController
{
    // 设置控制器中间件
    protected $middleware = [
        \app\home\middleware\LoginAuth::class
    ];
    // 初始化
    protected function initialize()
    {
        // 继承初始化
        parent::initialize();

        $this->CommentModel = new CommentModel();
    }
    // 评论
    public function add()
    {
        if ($this->request->isPost()) {
            // 通过中间件将登录用户数据赋值
            $LoginUser = $this->request->LoginUser;
            // 接收帖子id
            $postid = $this->request->param('postid');
            // 接收父级id（是否为楼主）
            $pid = $this->request->param('pid');
            // 查询该贴
            $post = PostModel::find($postid);
            if (!$post) {
                $this->error('帖子不存在，无法评论');
            }
            // 接收评论内容
            $content = $this->request->param('content');
            // 评论数据
            $data = [
                'content' => $content,
                'userid' => $LoginUser['id'],
                'postid' => $postid,
                'accept' => 0
            ];
            // 封装数据
            if ($pid) {
                // 处理回复的评论
                $level = CommentModel::where(['id' => $pid])->value('level');
                // 追加封装数据
                $data['pid'] = $pid;
                $data['level'] = $level + 1;
            } else {
                $data['pid'] = 0;
                $data['level'] = 0;
            }
            // 验证数据
            try {
                validate(CommentValiDate::class)->check($data);
            } catch (ValidateException $e) {
                $this->error($e->getMessage());
            }
            $result = $this->CommentModel->save($data);
            if ($result != FALSE) {
                $this->success('评论成功');
            } else {
                $this->error('评论失败');
            }
        }
    }
    // 点赞
    public function like()
    {
        if ($this->request->isAjax()) {
            $userid = !empty($LoginUser['id']) ? $LoginUser['id'] : 0;
            $commentid = $this->request->param('commentid');
            $comment = $this->CommentModel->find($commentid);
            if (!$comment) {
                $this->error('评论不存在');
            }
            $LikeArr = explode(',', (string)$comment['like']);
            $LikeArr = array_filter($LikeArr);
            // 如果登录用户id不存在数组里则追加进数组里
            if (!in_array($userid, $LikeArr)) {
                $LikeArr[] = $userid;
                $LikeStr = implode(',', $LikeArr);
                $result = $this->CommentModel->update(['like' => $LikeStr], ['id' => $commentid]);
                if ($result !== FALSE) {
                    $this->success('点赞成功');
                } else {
                    $this->error('点赞失败');
                }
            } else {
                foreach ($LikeArr as $key => $item) {
                    if ($item == $userid) {
                        unset($LikeArr[$key]);
                        break;
                    }
                }
                // 封装数组
                $LikeData = [
                    'like' => implode(',', $LikeArr),
                ];
                // 更新数据
                $result = $comment->save($LikeData);

                if ($result !== true) {
                    $this->error('取消点赞失败');
                } else {
                    $this->success('已取消点赞');
                }
            }
        }
    }

    //删除评论
    public function del()
    {
        if ($this->request->isAjax()) {
            $comid = $this->request->param('comid');
            $comment = $this->CommentModel->find(['id' => $comid]);
            if (!$comment) {
                $this->error('评论不存在');
            }
            $CommentList = CommentModel::select();
            $CommentData = getSubTree($CommentList, $comid);
            // 存放评论id的数据
            $IdArr = [];
            // 循环
            foreach ($CommentData as $item) {
                // 把循环出来的id放一起
                $IdArr[] = $item['id'];
            }
            // 追加id并且放在该数组里第一位
            array_unshift($IdArr, $comment['id']);
            // 删除
            $result = CommentModel::destroy($IdArr);

            if ($result !== true) {
                $this->error('删除评论失败');
            } else {
                $this->success('删除评论成功');
            }
        }
    }

    // 采纳
    public function accept()
    {
        if ($this->request->isAjax()) {
            // 接收评论id
            $commentid = $this->request->param('commentid');
            // 查询评论
            $comment = $this->CommentModel->find($commentid);
            // 查询帖子
            $post = PostModel::find($comment['postid']);
            // 查询该评论的用户信息
            $User = UserModel::find($comment['userid']);

            if (!$comment) {
                $this->error('该评论不存在，无法采纳');
            }

            if (!$post) {
                $this->error('该帖子不存在，无法采纳');
            }

            if (!$User) {
                $this->error('用户不存在，无法采纳');
            }

            if ($comment['accept'] > 0 && $post['accept'] > 0) {
                $this->error('该帖子已有采纳，无法采纳');
            }
            /* 
                评论表 更新采纳字段
                帖子表 需要更新采纳人字段
                用户表 悬赏积分加到用户
                消费记录 新增获取到积分记录
            */
            // 开启事务操作
            CommentModel::startTrans();
            PostModel::startTrans();
            UserModel::startTrans();
            RecordModel::startTrans();
            // 更新评论表数据
            $comment->accept = 1;
            // 执行
            $CommentStatus = $comment->save();
            // 判断
            if ($CommentStatus === FALSE) {
                $this->error('评论采纳状态更新失败');
            }

            // 更新帖子表数据
            $post->accept = $comment['userid'];
            // 执行
            $PostStatus = $post->save();
            // 判断
            if ($PostStatus === FALSE) {
                CommentModel::rollback();
                $this->error('帖子采纳人更新失败');
            }
            // 更新用户表
            $point = bcadd((string)$User['point'], (string)$post['point']);

            $User->point = $point;

            $UserStatus = $User->save();

            if ($UserStatus === FALSE) {
                CommentModel::rollback();
                PostModel::rollback();
                $this->error('用户积分更新失败');
            }

            // 新增消费记录
            $RecordData = [
                'point' => $post['point'],
                'content' => "您发表的评论：{$comment['content']}获得了{$post['point']}积分",
                'state' => 2,
                'userid' => $comment['userid']
            ];

            try {
                validate(RecordValiDate::class)->check($RecordData);
            } catch (ValidateException $e) {
                CommentModel::rollback();
                PostModel::rollback();
                UserModel::rollback();
                $this->error($e->getMessage());
            }

            $Record = new RecordModel();

            $RecordStatus = $Record->save($RecordData);

            if ($RecordStatus === FALSE) {
                CommentModel::rollback();
                PostModel::rollback();
                UserModel::rollback();
                $this->error('新增消费记录失败');
            }

            if ($CommentStatus === FALSE || $PostStatus === FALSE || $UserStatus === FALSE || $RecordStatus === FALSE) {
                CommentModel::rollback();
                PostModel::rollback();
                UserModel::rollback();
                RecordModel::rollback();
                $this->error('采纳失败');
            } else {
                CommentModel::commit();
                PostModel::commit();
                UserModel::commit();
                RecordModel::commit();
                $this->success('采纳成功');
            }
        }
    }
}
